import {
  Feature,
  Map,
  Overlay,
  View
} from "ol";
import {
  transformExtent,
  transform,
  get as getProjection,
  Projection,
} from "ol/proj";
import {
  getWidth,
  getTopLeft
} from "ol/extent.js";
import {
  WMTS,
  XYZ as XYZSource,
  TileWMS,
  Vector as VectorSource,
  Cluster,
} from "ol/source";
import {
  Tile as TileLayer,
  Vector as VectorLayer,
  Group as LayerGroup,
} from "ol/layer";
import WMTSTileGrid from "ol/tilegrid/WMTS";
import GeoJSON from "ol/format/GeoJSON";
import proj4 from "proj4";
import {
  register
} from "ol/proj/proj4";
import {
  Circle,
  Fill,
  Icon,
  Stroke,
  Style,
  Text
} from "ol/style";
import {
  MousePosition,
  ScaleLine
} from "ol/control";
import Draw, {
  createBox
} from "ol/interaction/Draw";
import {
  createStringXY
} from "ol/coordinate";
import {
  Point,
  LineString,
  Polygon
} from "ol/geom";
import * as echarts from "echarts";
import {
  ElMessage
} from "element-plus";
import WKT from "terraformer-wkt-parser";
import {
  unByKey
} from "ol/Observable";
import {
  defaults as defaultInteractions
} from "ol/interaction";
import * as turf from "@turf/turf";
import {
  TDKEY,
  EV_SERVER,
  GEOSERVERURL
} from "@/config/mapConfig.js";
import Graticule from 'ol/layer/Graticule';
import {
  getArea,
  getLength
} from "ol/sphere";
import elecFence from '@/assets/geojson/连云港电子围栏.json'
import seaShp from '@/assets/geojson/灌云6万亩海域坐标矢量面.json'
import towerPoint from '@/assets/geojson/岸基高空铁塔视频监测.json'
import towerPolygon from '@/assets/geojson/铁塔视频监测范围-4326.json'
import towerPointPng from "@/assets/image/layerIcon/red.png"
import fengliPoint from '@/assets/geojson/海上风力塔视频监测.json'
import fengliPolygon from '@/assets/geojson/风力塔视频监测范围-4326.json'
import lygPolygon from '@/assets/geojson/连云港区县.json'
import fengliPointPng from "@/assets/image/layerIcon/purple.png"
import cameraData from "@/assets/geojson/摄像头.json"
import cameraPng from "@/assets/image/layerIcon/sys.png"
import {
  useConfigStore
} from "../store/useConfigStore";
import {
  storeToRefs
} from "pinia";
import gcj02Mecator from "./gcj02Mecator";
import wurenji from "@/assets/image/wurenji.png";
import radar from "@/assets/image/radar.png";
const userConfigStore = useConfigStore();
const {
  videoDialogVisible,
  pickSXT
} = storeToRefs(userConfigStore);
const uavArr = [{
    name: "东台河闸东宏站型",
    lon: "120.848910",
    lat: "32.943476"
  },
  {
    name: "射阳县黄沙港镇运粮河闸",
    lon: "120.404109",
    lat: "33.932261"
  },
  {
    name: "H5L滨海振东河闸沿海D",
    lon: "120.265669",
    lat: "34.236551"
  },
  {
    name: "大丰港口二期码头沿海",
    lon: "120.718468",
    lat: "33.221592"
  },
  {
    name: "赣榆柘汪大新庄机房-落地三管塔",
    lon: "119.208401",
    lat: "35.024801"
  },
  {
    name: "东区_东连岛_宏站型",
    lon: "119.462735",
    lat: "34.721149"
  },
  {
    name: "环渔2东",
    lon: "120.958869",
    lat: "32.568440"
  },
  {
    name: "启东市篙枝港机房",
    lon: "121.760826",
    lat: "31.993311"
  }
];

const radarArr = [{
    name: "高公岛",
    lon: "119.475833",
    lat: "34.703278"
  },
  {
    name: "燕尾港东六圩",
    lon: "119.762731",
    lat: "34.501486"
  },
  {
    name: "秦山岛",
    lon: "119.280769",
    lat: "34.870242°"
  },
  {
    name: "燕尾港k波段雷达",
    lon: "119.787247",
    lat: "34.479883"
  },
  {
    name: "连岛",
    lon: "119.444861",
    lat: "34.774556"
  },
];

var map = null; //Map对象
var viewer = null; //view对象
var draw = null; //绘制对象
var mapMouseMove = null;
var drawStatus = false; //绘制状态
var feature = null; //绘制的feature
var helpTooltipElement = null; //鼠标移动时显示的提示框
var listener = null; //监听器
var measureTooltipElement = null; //
var measureTooltip = null; //测量提示框
var drawElements = []; //绘制的feature
var helpTooltip = null; //鼠标移动时显示的提示框
var drawLayers = []; //绘制的feature
var continuePolygonMsg = "单击以继续绘制多边形"; //鼠标移动时显示的提示框
var mapMouseMoveOfArea = null;
var sketch = null;
var towerLayerGroup = null;
var seaLayer = null; //海图底图Layer
var elecFenceLayer = null;
var uavLayer = null;

var ChartDisplayMode = "All"; //
var ChartColorMode = "DayTime";

var radarLayer = null;
var noteLayer = null; // 注记图层
var graticuleLayer = null; //经纬网图层

export var towerPointLayer1 = null;
export var towerPointLayer2 = null;
export var towerCircleLayer1 = null;
export var towerCircleLayer2 = null;
export var towerVideoLayer = null;


export function changeNoteLayerVisible(flag) {
  noteLayer.setVisible(flag);
}
export function changeGraticuleLayerVisible(flag) {
  graticuleLayer.setVisible(flag);
}
// 打开雷达监控
export function openRadarLayer() {
  if (!uavLayer) {
    // 创建矢量源
    const uavFeatures = radarArr.map(item => {
      const feature = new Feature({
        geometry: new Point(
          transform([parseFloat(item.lon), parseFloat(item.lat)], "EPSG:4326", "EPSG:3857")
        )
      });
      // 存储原始数据用于后续交互
      feature.set("radarData", item);
      return feature;
    });

    const vectorSource = new VectorSource({
      features: uavFeatures
    });

    // 创建矢量图层
    radarLayer = new VectorLayer({
      name: "uavLayer",
      source: vectorSource,
      style: function (feature) {
        console.log(feature);
        return new Style({
          image: new Icon({
            src: radar, // 使用摄像头图标
            scale: 0.2, // 图标大小
          }),
          // 可选：添加文字标签
          text: new Text({
            text: feature.values_.radarData.name, // 这里可能需要动态绑定
            font: "12px Microsoft YaHei",
            textBaseline: "bottom",
            offsetY: 30,
            fill: new Fill({
              color: "#fff"
            }),
            stroke: new Stroke({
              color: "#4281EA",
              width: 2
            })
          })
        })
      },
    });
    map.addLayer(radarLayer);
  } else {
    radarLayer.setVisible(true);
  }
}

export function closeRadarLayer() {
  if (radarLayer) {
    radarLayer.setVisible(false);
  }
}

export function openUAVLayer() {
  if (!uavLayer) {
    // 创建矢量源
    const uavFeatures = uavArr.map(item => {
      const feature = new Feature({
        geometry: new Point(
          transform([parseFloat(item.lon), parseFloat(item.lat)], "EPSG:4326", "EPSG:3857")
        )
      });
      // 存储原始数据用于后续交互
      feature.set("uavData", item);
      return feature;
    });

    const vectorSource = new VectorSource({
      features: uavFeatures
    });

    // 创建矢量图层
    uavLayer = new VectorLayer({
      name: "uavLayer",
      source: vectorSource,
      style: function (feature) {
        console.log(feature);
        return new Style({
          image: new Icon({
            src: wurenji, // 使用摄像头图标
            scale: 0.2, // 图标大小
          }),
          // 可选：添加文字标签
          text: new Text({
            text: feature.values_.uavData.name, // 这里可能需要动态绑定
            font: "12px Microsoft YaHei",
            textBaseline: "bottom",
            offsetY: 30,
            fill: new Fill({
              color: "#fff"
            }),
            stroke: new Stroke({
              color: "#4281EA",
              width: 2
            })
          })
        })
      },
    });
    map.addLayer(uavLayer);
  } else {
    uavLayer.setVisible(true);
  }
}

export function closeUAVLayer() {
  if (uavLayer) {
    uavLayer.setVisible(false);
  }
}

export function updateSeaLayerStyle(styleName, index) {
  if (seaLayer) {
    if (index == 0) {
      ChartDisplayMode = styleName;
    }
    if (index == 1) {
      ChartColorMode = styleName;
    }
    seaLayer.getSource().updateParams({
      STYLES: `${ChartDisplayMode},${ChartColorMode},Tradition,FiveMeter,Chinese`
    })
  }

}


export function openElecFenceLayer() {
  if (elecFenceLayer) {
    elecFenceLayer.setVisible(true);
  }
}
export function closeElecFenceLayer() {
  if (elecFenceLayer) {
    elecFenceLayer.setVisible(false);
  }
}

// 关闭geoserver服务中WMTS瓦片
export function removeGeoserverWMTS(layerName) {
  const layer = map.getLayers().getArray().find(layer => layer.get('name') === layerName);
  if (layer) {
    map.removeLayer(layer);
  }
}

// 添加geoserver服务中WMTS瓦片
export function addGeoserverWMTS(layerName) {
  const layer = new TileLayer({
    name: layerName,
    source: new TileWMS({
      url: `${GEOSERVERURL}geoserver/marineRanch/wms?`,
      params: {
        LAYERS: "marineRanch:" + layerName,
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        SRS: "EPSG:4326",
        SERVICE: "WMS",
      },
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
    }),
  });
  map.addLayer(layer);
}

// 关闭海图
export function closeSeaLayer() {
  if (seaLayer) {
    seaLayer.setVisible(false);
  }
}

// 打开海图
export function openSeaLayer() {
  if (seaLayer) {
    seaLayer.setVisible(true);
  }
}


// 关闭铁塔图层
export function closeTowerVideoLayer() {
  if (towerLayerGroup) {
    map.removeLayer(towerLayerGroup);
  }
}

// 添加铁塔矢量数据
export function openTowerVideoLayer() {
  // 岸基高空铁塔
  towerPointLayer1 = new VectorLayer({
    source: new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857"
      }).readFeatures(towerPoint)
    }),
    name: "towerPoint",
    style: new Style({
      image: new Icon({
        src: towerPointPng,
        scale: 0.5, // 图标大小
      }),
    })
  });
  towerCircleLayer1 = new VectorLayer({
    source: new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857"
      }).readFeatures(towerPolygon)
    }),
    name: "towerPoint",
    style: new Style({
      stroke: new Stroke({
        color: "#FF0000", // 边线颜色
        width: 3, // 边线宽度
        lineDash: [8, 8] // 虚线模式：15像素实线 + 5像素空白
      })
    })
  });
  // 风力铁塔
  towerPointLayer2 = new VectorLayer({
    source: new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857"
      }).readFeatures(fengliPoint)
    }),
    name: "towerPoint",
    style: new Style({
      image: new Icon({
        src: fengliPointPng,
        scale: 0.5, // 图标大小
      }),
    })
  });
  towerCircleLayer2 = new VectorLayer({
    source: new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857"
      }).readFeatures(fengliPolygon)
    }),
    name: "towerPoint",
    style: new Style({
      stroke: new Stroke({
        color: "#940ECD", // 边线颜色
        width: 3, // 边线宽度
        lineDash: [8, 8] // 虚线模式：15像素实线 + 5像素空白
      })
    })
  });
  // 摄像头数据
  towerVideoLayer = new VectorLayer({
    name: "cameraLayer",
    source: new VectorSource({
      features: cameraData.map(item => {
        const feature = new Feature({
          geometry: new Point(
            transform(item.position, "EPSG:4326", "EPSG:3857")
          )
        });
        // 存储原始数据用于后续交互
        feature.set("cameraData", item);
        return feature;
      })
    }),
    style: function (feature) {
      console.log(feature);
      return new Style({
        image: new Icon({
          src: cameraPng, // 使用摄像头图标
          scale: 0.5, // 图标大小
        }),
        // 可选：添加文字标签
        text: new Text({
          text: feature.values_.cameraData.name, // 这里可能需要动态绑定
          font: "12px Microsoft YaHei",
          textBaseline: "bottom",
          offsetY: 30,
          fill: new Fill({
            color: "#fff"
          }),
          stroke: new Stroke({
            color: "#4281EA",
            width: 2
          })
        })
      })
    },
    zIndex: Infinity,
    name: "cameraLayer"
  });

  // 3. 添加图层到地图
  towerLayerGroup = new LayerGroup({
    layers: [towerPointLayer1, towerPointLayer2, towerCircleLayer1, towerCircleLayer2, towerVideoLayer],
  });
  map.addLayer(towerLayerGroup);
}

/*
 *定位到初始为止
 */
export function setViewCenterOl() {
  map.getView().animate({
    center: transform([119.44, 34.8], "EPSG:4326", "EPSG:3857"),
    zoom: 9.5,
  });
}
/*
 *  初始化地图
 */
export function initMap() {
  // 销毁地图
  if (map !== null) {
    map.setTarget(null);
    map.dispose();
    map = null;
    let element1 = document.getElementById("map");
    while (element1.firstChild) {
      element1.removeChild(element1.firstChild);
    }
  }
  viewer = new View({
    center: transform([119.44, 34.8], "EPSG:4326", "EPSG:3857"),
    zoom: 9.5,
    minZoom: 1,
    maxZoom: 19,
    // extent: transformExtent(
    //     [105.531585, 37.894280, 127.357974, 30.054311],
    //     "EPSG:4326",
    //     "EPSG:3857"
    // ),
  });
  // 添加经纬网
  graticuleLayer = new Graticule({
    strokeStyle: new Stroke({
      color: 'rgba(255,0,0,0.8)', // 线条颜色和透明度
      width: 1.5, // 线宽
      lineDash: [5, 5] // 虚线样式（可选）
    }),
    showLabels: true, // 显示经纬度标注
    wrapX: false, // 禁止水平重复（避免国际日期变更线问题）
    maxLines: 100, // 最大线条数量（防性能过载）[1,8](@ref)
    latLabelPosition: 0, // 关键参数：1=左侧
    latLabelStyle: new Text({
      font: '10px sans-serif', // 修改字体
      textAlign: 'left', // 左对齐（'left' 或 'start'）
      fill: new Fill({
        color: '#000'
      }), // 红色文字
      stroke: new Stroke({
        color: '#FFFFFF',
        width: 4
      }), // 白色描边
      padding: [4, 8], // 内边距（文本与背景之间的间距）
      offsetX: 5
    }),
    lonLabelStyle: new Text({
      font: '10px sans-serif', // 修改字体
      textAlign: 'center', // 左对齐（'left' 或 'start'）
      fill: new Fill({
        color: '#000'
      }), // 红色文字
      stroke: new Stroke({
        color: '#FFFFFF',
        width: 4
      }), // 白色描边
      padding: [4, 8], // 内边距（文本与背景之间的间距）
      offsetY: -10
    }),
    projection: 'EPSG:3857',
    labelClassName: 'custom-lat-label', // 自定义类名
    // extent: [70, 10, 140, 50],    // 限定渲染范围（[minLon, minLat, maxLon, maxLat]）[5](@ref)
    visible: false
  });
  seaLayer = addSeaImg(); //添加海图
  elecFenceLayer = addElecFence();
  noteLayer = addAutoLabelMap();
  map = new Map({
    target: "map",
    view: viewer,
    layers: [
      // addTiandituImg(),
      // addTiandituLabel(),
      addAutoMap(),
      seaLayer,
      noteLayer,
      graticuleLayer, // 添加经纬网
      addLygShp(), //添加连云港行政区划
      elecFenceLayer, //添加电子围栏
      addSeaShp(), //添加海域矢量
    ], //高德影像地图、注记
  });
  // 添加比例尺
  const scaleLineControl = new ScaleLine({
    units: "metric", //设置比例尺单位，有degrees、imperial、us、nautical或metric
    className: "custom-scale-line",
    text: true, // 显示标尺文字
    target: document.getElementById("scaleLine"),
  });
  map.addControl(scaleLineControl);
  // 添加鼠标悬浮态坐标
  const mousePositionControl = new MousePosition({
    coordinateFormat: function (e) {
      let stringifyFunc = createStringXY(6);
      let str = stringifyFunc(e);
      return (
        "经度: " +
        DDDToDMS(str.split(",")[0]) +
        "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
        " 纬度: " +
        DDDToDMS(str.split(",")[1])
      );
    },
    projection: "EPSG:4326",
    className: "custom-mouse-position",
    target: document.getElementById("mousePosition"),
  });
  map.addControl(mousePositionControl);
  // 为map添加鼠标移动事件监听，当指向标注时改变鼠标光标状态
  map.on("pointermove", function (e) {
    let pixel = map.getEventPixel(e.originalEvent);
    let hit = map.hasFeatureAtPixel(pixel);
    map.getTargetElement().style.cursor = hit ? "pointer" : "";
  });
  window.map = map;

  // 处理底图点击事件
  map.on("click", (evt) => {
    //投影坐标转为地理坐标
    // let lonLat = evt.coordinate;
    // let point = transform(lonLat, "EPSG:3857", "EPSG:4326");
    // console.log(point);
    map.forEachFeatureAtPixel(evt.pixel, (feature, layer) => {
      if (feature) {
        let layerData = feature.getProperties();
        // 点击摄像头图标
        if (layerData.cameraData) {
          videoDialogVisible.value = true;
          pickSXT.value = layerData.cameraData;
        }
      }
    });

  });
}

/*
 *添加电子围栏
 */
function addElecFence() {
  // 创建一个VectorSource实例，并使用GeoJSON数据
  const vectorSource = new VectorSource({
    format: new GeoJSON(),
    // 使用上面的GeoJSON数据对象
    features: new GeoJSON({
      featureProjection: "EPSG:3857"
    }).readFeatures(elecFence)
  });
  // 创建VectorLayer并将VectorSource添加到该层
  const vectorLayer = new VectorLayer({
    source: vectorSource,
    name: "elecFence",
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 0, 0, 0.2)", // 填充颜色，这里使用半透明红色
      }),
      stroke: new Stroke({
        color: "#FFFF00", // 边线颜色
        width: 2 // 边线宽度
      })
    })
  });
  return vectorLayer;
}

// 添加连云港6万亩海域矢量
function addSeaShp() {
  // 创建一个VectorSource实例，并使用GeoJSON数据
  const vectorSource = new VectorSource({
    format: new GeoJSON(),
    // 使用上面的GeoJSON数据对象
    features: new GeoJSON({
      featureProjection: "EPSG:3857"
    }).readFeatures(seaShp)
  });
  // 创建VectorLayer并将VectorSource添加到该层
  const vectorLayer = new VectorLayer({
    source: vectorSource,
    name: "elecFence",
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 255, 0, 0.2)", // 填充颜色，这里使用半透明红色
      }),
      stroke: new Stroke({
        color: "#FFFF00", // 边线颜色
        width: 2 // 边线宽度
      })
    })
  });
  return vectorLayer;

}

// 添加连云港行政区划矢量
function addLygShp() {
  // 创建一个VectorSource实例，并使用GeoJSON数据
  const vectorSource = new VectorSource({
    format: new GeoJSON(),
    // 使用上面的GeoJSON数据对象
    features: new GeoJSON({
      featureProjection: "EPSG:3857"
    }).readFeatures(lygPolygon)
  });
  // 创建VectorLayer并将VectorSource添加到该层
  const vectorLayer = new VectorLayer({
    source: vectorSource,
    name: "elecFence",
    style: (feature) => {
      return new Style({
        // fill: new Fill({
        //   color: "rgba(255, 255, 0, 0.2)", // 填充颜色，这里使用半透明红色
        // }),
        stroke: new Stroke({
          color: "#0D74DB", // 边线颜色
          width: 2 // 边线宽度
        }),
        text: new Text({
          // 位置
          textAlign: "center",
          // 基准线
          textBaseline: "middle",
          // 文字样式
          font: "bold 16px 微软雅黑",
          // 文本内容
          text: `${feature.get("县级") ? feature.get("县级") : ""}`,
          // 文字颜色
          fill: new Fill({
            color: "#000",
          }),
          // 文字背景
          stroke: new Stroke({
            color: "#fff",
            width: 2
          }),
        }),
      })
    }
  });
  return vectorLayer;

}
// 格式化长度
function formatLength(line) {
  const length = getLength(line, {
    projection: "EPSG:3857"
  });
  let output;
  let kilometer = Math.round((length / 1000) * 100) / 100 + " " + "km";
  let seaMile =
    (0.5399568 * (Math.round((length / 1000) * 100) / 100)).toFixed(2) +
    " " +
    "海里";
  output = `<div>${seaMile}</div><div>${kilometer}</div>`;
  return output;
}

// 格式化面积
function formatArea(polygon) {
  const area = getArea(polygon, {
    projection: "EPSG:3857"
  });
  let output;
  let kilometer =
    Math.round((area / 1000000) * 100) / 100 + " " + "平方公里";
  let seaMile =
    (0.29155285 * (Math.round((area / 1000000) * 100) / 100)).toFixed(2) +
    " " +
    "平方海里";
  output = `<div>${seaMile}</div><div>${kilometer}</div>`;
  // if (area > 10000) {
  //   output =
  //     Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
  // }
  return output;
}

function createMeasureTooltip() {
  if (measureTooltipElement) {
    measureTooltipElement.parentNode.removeChild(
      measureTooltipElement
    );
  }
  measureTooltipElement = document.createElement("div");
  measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
  measureTooltip = new Overlay({
    element: measureTooltipElement,
    offset: [0, -15],
    positioning: "bottom-center",
    stopEvent: false,
    insertFirst: false,
  });
  drawElements.push(measureTooltip);
  map.addOverlay(measureTooltip);
}

function createHelpTooltip() {
  if (helpTooltipElement) {
    helpTooltipElement.parentNode.removeChild(helpTooltipElement);
  }
  helpTooltipElement = document.createElement("div");
  helpTooltipElement.className = "ol-tooltip hidden";
  helpTooltip = new Overlay({
    element: helpTooltipElement,
    offset: [15, 0],
    positioning: "center-left",
  });
  map.addOverlay(helpTooltip);
}
// 测距功能
export function distanceMeasure() {
  drawStatus = true;
  draw && map.removeInteraction(draw);
  let source = new VectorSource();
  const layer = new VectorLayer({
    source: source,
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 255, 255, 0.2)",
      }),
      stroke: new Stroke({
        color: "#FF0080",
        width: 4,
      }),
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: "#FF0080",
        }),
      }),
    }),
  });
  mapMouseMove = map.on("pointermove", (ev) => {
    if (!drawStatus) {
      return;
    }
    let helpMsg = "点击开始测量";
    if (feature) {
      helpMsg = "双击结束测量";
    }
    helpTooltipElement.innerHTML = helpMsg;
    helpTooltip.setPosition(ev.coordinate);
    helpTooltipElement.classList.remove("hidden");
  });
  map.getViewport().addEventListener("mouseout", () => {
    helpTooltipElement.classList.add("hidden");
  });
  draw = new Draw({
    source,
    type: "LineString",
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 255, 255, 0.2)",
      }),
      stroke: new Stroke({
        color: "rgba(0, 0, 0, 0.5)",
        lineDash: [10, 10],
        width: 4,
      }),
      image: new Circle({
        radius: 5,
        stroke: new Stroke({
          color: "rgba(0, 0, 0, 0.7)",
        }),
        fill: new Fill({
          color: "rgba(255, 255, 255, 0.2)",
        }),
      }),
    }),
  });
  // 开始坚挺绘制
  draw.on("drawstart", (evt) => {
    feature = evt.feature;
    let tooltipCoord = evt.coordinate;
    listener = feature.getGeometry().on("change", (evt) => {
      const geom = evt.target;
      let output = formatLength(geom);
      tooltipCoord = geom.getLastCoordinate();
      measureTooltipElement.innerHTML = output;
      measureTooltip.setPosition(tooltipCoord);
    });
  });
  // 双击绘制完成
  draw.on("drawend", () => {
    measureTooltipElement.className = "ol-tooltip ol-tooltip-static";
    measureTooltip.setOffset([0, -7]);
    feature = null;
    measureTooltipElement = null;
    createMeasureTooltip();
    unByKey(listener);
  });
  createHelpTooltip();
  createMeasureTooltip();
  map.addLayer(layer);
  drawLayers.push(layer);
  map.addInteraction(draw);
}

// 面积测量
export function areaMeasure() {
  drawStatus = true;
  map.removeInteraction(draw);
  mapMouseMoveOfArea = map.on("pointermove", (evt) => {
    if (evt.dragging || !drawStatus) {
      return;
    }
    let helpMsg = "单击以开始绘制";
    if (sketch) {
      const geom = sketch.getGeometry();
      if (geom instanceof Polygon) {
        helpMsg = continuePolygonMsg;
      }
    }
    helpTooltipElement.innerHTML = helpMsg;
    helpTooltip.setPosition(evt.coordinate);
    helpTooltipElement.classList.remove("hidden");
  });
  map.getViewport().addEventListener("mouseout", () => {
    helpTooltipElement.classList.add("hidden");
  });
  const source = new VectorSource();
  const layer = new VectorLayer({
    source: source,
    style: {
      "fill-color": "rgba(255, 0, 128, 0.2)",
      "stroke-color": "#FF0080",
      "stroke-width": 2,
      "circle-radius": 7,
      "circle-fill-color": "#FF0080",
    },
  });
  draw = new Draw({
    source: source,
    type: "Polygon",
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 255, 255, 0.2)",
      }),
      stroke: new Stroke({
        color: "rgba(0, 0, 0, 0.5)",
        lineDash: [10, 10],
        width: 2,
      }),
      image: new Circle({
        radius: 5,
        stroke: new Stroke({
          color: "rgba(0, 0, 0, 0.7)",
        }),
        fill: new Fill({
          color: "rgba(255, 255, 255, 0.2)",
        }),
      }),
    }),
  });
  map.addInteraction(draw);
  map.addLayer(layer);
  drawLayers.push(layer);
  createMeasureTooltip();
  createHelpTooltip();
  draw.on("drawstart", (evt) => {
    sketch = evt.feature;
    let tooltipCoord = evt.coordinate;
    listener = sketch.getGeometry().on("change", (evt) => {
      const geom = evt.target;
      let output;
      if (geom instanceof Polygon) {
        output = formatArea(geom);
        tooltipCoord = geom.getInteriorPoint().getCoordinates();
      } else if (geom instanceof LineString) {
        output = formatLength(geom);
        tooltipCoord = geom.getLastCoordinate();
      }
      measureTooltipElement.innerHTML = output;
      measureTooltip.setPosition(tooltipCoord);
    });
  });
  draw.on("drawend", () => {
    measureTooltipElement.className = "ol-tooltip ol-tooltip-static";
    measureTooltip.setOffset([0, -7]);
    sketch = null;
    measureTooltipElement = null;
    createMeasureTooltip();
    unByKey(listener);
  });
}


// 移除量算图层

export function removeMeasureDrawLayer() {
  for (let i = 0; i < drawLayers.length; i++) {
    map.removeLayer(drawLayers[i]);
  }
  for (let i = 0; i < drawElements.length; i++) {
    map.removeOverlay(drawElements[i]);
  }
  drawLayers = [];
  drawElements = [];
  continuePolygonMsg = null;
  map.removeInteraction(draw);
  unByKey(mapMouseMove);
  unByKey(mapMouseMoveOfArea);
  drawStatus = false;
  const element = document.getElementsByClassName("ol-tooltip");
  element[0].classList.add("hidden");
}
/*
 *定位到指定位置
 */
export function setViewLocation(lon, lat) {
  map.getView().animate({
    center: transform([lon, lat], "EPSG:4326", "EPSG:3857"),
    zoom: 17,
  });
}


/*
 *获取参数（3857）
 */
function commonParam() {
  let projection = getProjection("EPSG:3857");
  let projectionExtent = projection.getExtent();
  let size = getWidth(projectionExtent) / 256;
  let resolutions = new Array(16);
  let matrixIds = new Array(16);
  for (let i = 0; i < 16; ++i) {
    resolutions[i] = size / Math.pow(2, i);
    matrixIds[i] = i;
  }
  return {
    projection,
    projectionExtent,
    resolutions,
    matrixIds,
  };
}

function commonParamOf4490() {
  proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs");
  //使proj4中定义的投影在OpenLayers中可用。
  register(proj4);
  //创建"EPSG:4490"的Projection实例，Openlayers将可以从Peoj4js中获取转换函数。
  let projection = new Projection({
    code: "EPSG:4490", //EPSG code
    extent: [-180, -90, 180, 90],
    worldExtent: [-180, -90, 180, 90],
    units: "degrees", //Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or `'us-ft'.
  });
  let projectionExtent = projection.getExtent();
  let size = getWidth(projectionExtent) / 256;
  let resolutions = new Array(16);
  let matrixIds = new Array(16);
  for (let i = 0; i < 16; ++i) {
    resolutions[i] = size / Math.pow(2, i);
    matrixIds[i] = i;
  }
  return {
    projection,
    projectionExtent,
    resolutions,
    matrixIds,
  };
}
/*
 *处理feature
 */
function handleFeature(type, feature) {
  feature.setStyle(
    new Style({
      image: new Icon({
        src: type == "jyfc" ? jyfcPng : gnssPng,
        scale: 0.1, // 图标大小
      }),
      text: new Text({
        text: feature.get("siteData").place,
        font: "14px Microsoft YaHei",
        fill: new Fill({
          color: "#fff",
        }),
        textBaseline: "bottom",
        offsetY: -10,
        stroke: new Stroke({
          color: "#9E9E9E",
          width: 1,
        }),
        // backgroundFill:new Fill({
        //   color: "#1D3C4A90",
        // }),
        // backgroundStroke: new Stroke({
        //   color: "#00C7EC"
        // })
      }),
    })
  );
}
// 经纬度转度分秒
const DDDToDMS = (_data) => {
  if (!_data) return ""
  let value = parseFloat(_data);
  let _d = Math.floor(value); //度
  let _m = Math.floor((value - _d) * 60); //分
  let _s = parseFloat(((value - _d) * 3600) % 60).toFixed(2); //精确小数点后面两位
  return _d + "°" + _m + "'" + _s + '"';
};
//tin网格函数---------------------------
//创建tin网格
export const creatZd = (activities) => {
  removeTextLayer(jybLayer, "jyb");
  removeTextLayer(fcbLayer, "fcb");
  removeTextLayer(gnss2Layer, "gnss2");
  activities.map((item, index) => {
    const timer = setTimeout(() => {
      item.loaded = true;
      addPoint(item.billboardList);
      addTin(item.tinList);
    }, 1000 * index);

    timers.push(timer); // 将定时器ID存入数组
  });
};
const addPoint = (billboardList) => {
  const layerSource = poiLayer.getSource();
  billboardList.forEach((i) => {
    const feature = new Feature({
      geometry: new Point(
        transform([i.longitude, i.latitude], "EPSG:4326", "EPSG:3857")
      ), // 转换坐标并创建点几何
    });
    feature.setStyle(
      new Style({
        image: new Circle({
          radius: 0, // 半径为0，使点不可见
        }),
      })
    );
    layerSource.addFeature(feature); // 将要素添加到矢量源
    poiFeatures.push(feature); // 存储要素以便后续删除
  });
};
const removePoi = () => {
  if (poiFeatures.length > 0) {
    const source = poiLayer.getSource();
    poiFeatures.forEach((feature) => {
      source.removeFeature(feature);
    });
    poiFeatures = [];
  }
};
const addTin = (tinList) => {
  const tinFeature = loadBillbordAndTin(tinList);

  const allFeatures = new GeoJSON().readFeatures(tinFeature, {
    dataProjection: "EPSG:4326", // GeoJSON数据的坐标系
    featureProjection: "EPSG:3857", // 地图的坐标系
  });
  const jiangSuFeatures = new GeoJSON({
    featureProjection: "EPSG:3857",
  }).readFeatures(jiangSu);
  //添加筛选逻辑
  const filteredFeatures = allFeatures.filter((allFeature) => {
    // 获取 OpenLayers 几何体的 GeoJSON 表示
    const allGeometry =
      allFeature.getGeometry().getType() === "Polygon" ?
      turf.polygon(allFeature.getGeometry().getCoordinates()) :
      turf.multiPolygon(allFeature.getGeometry().getCoordinates());

    return !jiangSuFeatures.some((jiangSuFeature) => {
      const jiangSuGeometry =
        jiangSuFeature.getGeometry().getType() === "Polygon" ?
        turf.polygon(jiangSuFeature.getGeometry().getCoordinates()) :
        turf.multiPolygon(jiangSuFeature.getGeometry().getCoordinates());

      return turf.booleanIntersects(allGeometry, jiangSuGeometry);
    });
  });

  const vectorSource = new VectorSource({
    features: filteredFeatures,
  });

  tinLayer.setSource(vectorSource);
};
export const removeEntities = () => {
  recoverTextLayer(jybLayer, "jyb");
  recoverTextLayer(fcbLayer, "fcb");
  recoverTextLayer(gnss2Layer, "gnss2");
  timers.forEach((timer) => clearTimeout(timer));
  timers = []; // 清空定时器数组
  removePoi();
  tinLayer.setSource();
};
const loadBillbordAndTin = (zdList) => {
  const zda = [];
  //获取zdList中所有点的经纬度放入到数组zda中
  for (const i in zdList) {
    const zdmi = zdList[i];
    zda.push(turf.point([zdmi.longitude, zdmi.latitude]));
  }
  //将zda数组转换为FeatureCollection
  const collection = turf.featureCollection(zda);
  //将FeatureCollection转换为tin
  const tin = turf.tin(collection);
  return tin;
};
//tin网格函数------------------------------------

// 添加市域边界图层
export async function addShiBorderLayer(code) {
  map.removeLayer(allCityBorderLayer);
  let {
    data
  } = await getArea(code ? code : 320000);
  if (data.code == 200) {
    let result = data.data;

    let childGeojson = {
      type: "FeatureCollection",
      features: result.children.map((a) => {
        return {
          type: "Feature",
          properties: {
            name: a.areaName,
            adcode: a.areaCode,
          },
          geometry: WKT.parse(a.geom),
        };
      }),
    };
    // 创建子级边界
    const vectorSource = new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857",
      }).readFeatures(childGeojson),
    });
    // 创建VectorLayer并将VectorSource添加到该层
    allCityBorderLayer = new VectorLayer({
      source: vectorSource,
      name: "clickLayer",
      style: (feature) => {
        return new Style({
          //填充色
          // fill: new Fill({
          //   color: "rgba(255, 255, 255, 0.2)",
          // }),
          //边线颜色
          stroke: new Stroke({
            color: code ? "#ff0000" : "#D1D3A0",
            width: 2,
          }),
          text: new Text({
            // 位置
            textAlign: "center",
            // 基准线
            textBaseline: "middle",
            // 文字样式
            font: "bold 18px 微软雅黑",
            // 文本内容
            text: `${feature.get("name") ? feature.get("name") : ""}`,
            // 文字颜色
            fill: new Fill({
              color: "#0fc7ec",
            }),
            // 文字背景
            // stroke: new Stroke({ color: "#353535", width: 1 }),
          }),
          //点样式,继承image
          // image: new Circle({
          //   radius: 7,
          //   fill: new Fill({
          //     color: "#ffcc33",
          //   }),
          // }),
        });
      },
    });
    map.addLayer(allCityBorderLayer);
    zoomToExtent(map, allCityBorderLayer.getSource().getExtent());
  }
}
/*
 * 开启站点图标点击事件
 */
export function startBaseClickEvent() {
  // 监听地图点击事件
  baseClickEvent = (evt) => {
    // 用来存储当前选中的Feature
    let selectedFeature = null;
    // 遍历所有图标Feature
    let features = [];
    if (jyfcFeatures) {
      features = features.concat(
        jyfcFeatures.map((feature) => {
          return {
            type: "jyfc",
            obj: feature,
          };
        })
      );
    }
    if (gnssFeatures) {
      features = features.concat(
        gnssFeatures.map((feature) => {
          return {
            type: "gnss",
            obj: feature,
          };
        })
      );
    }
    // 检查点击的像素是否在当前Feature上
    map.forEachFeatureAtPixel(evt.pixel, function (feature) {
      if (!feature.get("features") || feature.get("features").length > 1 || exportImgStatus.value)
        return;
      let newFeature = feature.get("features")[0];
      // 当前点击的featuref非站点图标的情况处理
      if (!newFeature.get("siteData")) return;
      selectedFeature = newFeature;
      clickFeatureData.value = newFeature.get("siteData");
    });
    features.forEach(function (featureItem) {
      if (featureItem.obj == selectedFeature) {
        featureItem.obj.setStyle(dotStyle);
      } else {
        handleFeature(featureItem.type, featureItem.obj);
      }
    });
    if (selectedFeature) {
      const coordinate = evt.coordinate;
      siteOverlay.setPosition(coordinate);
    } else {
      siteOverlay.setPosition(undefined);
    }
  };
  map.on("singleclick", baseClickEvent);
}

export function closeSiteOverlay() {
  siteOverlay && siteOverlay.setPosition(undefined);
}

/*
 * 开启大屏图标点击事件
 */
export function startBaseClickEvent2() {
  // 监听地图点击事件
  baseClickEvent = (evt) => {
    // 用来存储当前选中的Feature
    let selectedFeature = null;
    // 遍历所有图标Feature
    let features = [];
    if (jybFeatures) {
      features = features.concat(
        jybFeatures.map((feature) => {
          return {
            type: "jyb",
            obj: feature,
          };
        })
      );
    }
    if (fcbFeatures) {
      features = features.concat(
        fcbFeatures.map((feature) => {
          return {
            type: "fcb",
            obj: feature,
          };
        })
      );
    }
    if (gnss2Features) {
      features = features.concat(
        gnss2Features.map((feature) => {
          return {
            type: "gnss2",
            obj: feature,
          };
        })
      );
    }
    // 检查点击的像素是否在当前Feature上
    map.forEachFeatureAtPixel(evt.pixel, function (feature) {
      let newFeature = feature;
      // 当前点击的featuref非站点图标的情况处理
      if (!newFeature.get("siteData")) return;
      selectedFeature = newFeature;

      clickFeatureData.value = newFeature.get("siteData");
    });
    if (selectedFeature) {
      const coordinate = evt.coordinate;

      siteOverlay.setPosition(coordinate);
    } else {
      siteOverlay.setPosition(undefined);
    }
  };
  map.on("singleclick", baseClickEvent);
}
/*
 * 结束站点图标点击事件
 */
export function endBaseClickEvent() {
  baseClickEvent && map.un("singleclick", baseClickEvent);
  baseClickEvent = null;
}



/*
 *绘制矩形框获取四至
 */
export function drawRectanglGetExtentOl(callback) {
  draw = new Draw({
    source: darwSource,
    type: "Circle",
    geometryFunction: createBox(),
    style: new Style({
      stroke: new Stroke({
        color: "#ffcc33",
        width: 4,
        lineDash: [10, 10], // 设置虚线样式
      }),
    }),
  });
  map.addInteraction(draw);
  draw.on("drawstart", () => {
    darwSource.clear();
  });
  draw.on("drawend", (evt) => {
    let extent = evt.feature.getGeometry().getExtent();
    const [minX, minY, maxX, maxY] = [0, 0, 1068, 653];
    const padding = [minY + 16, 1068 - maxX, 717 - maxY + 16, minX];
    map.getView().fit(extent, {
      padding,
      duration: 1000,
      callback: () => {
        let coord = [extent[0], extent[3]];
        let leftTopPosition = map.getPixelFromCoordinate(coord);
        let coord1 = [extent[2], extent[1]];
        let bottomRightPosition = map.getPixelFromCoordinate(coord1);
        let width = Math.abs(bottomRightPosition[0] - leftTopPosition[0]);
        let height = Math.abs(bottomRightPosition[1] - leftTopPosition[1]);
        let minx = leftTopPosition[0];
        let miny = leftTopPosition[1];
        callback(width, height, minx, miny);
      },
    });
  });
}
/*
 *移除绘制图层
 */
export function removeDrawLayerOl() {
  darwSource.clear();
  map.removeInteraction(draw);
  draw = null;
}
/*
 *加载图标数据
 */
export function addIcons(arr, type) {
  // 报废站点不进行展示
  arr = arr.filter(a => a.status !== 0);
  // 创建矢量源
  let featureArr = arr.map((point) => {
    const featureItem = new Feature({
      geometry: new Point(
        transform([point.longitude, point.latitude], "EPSG:4326", "EPSG:3857")
      ),
    });
    featureItem.set("siteData", point);
    // handleFeature(type, featureItem);
    return featureItem;
  });
  const vectorSource = new VectorSource({
    features: featureArr,
  });

  const clusterSource = new Cluster({
    distance: 60,
    minDistance: 20,
    source: vectorSource,
  });

  // 将矢量源添加到矢量层
  if (type == "jyfc") {
    jyfcFeatures = featureArr;
    jyfcLayer = new VectorLayer({
      source: clusterSource,
      style: function (feature) {
        const size = feature.get("features").length;
        return new Style({
          image: new Icon({
            src: jyfcPng,
            scale: 0.5, // 图标大小
          }),
          text: new Text({
            text: size == 1 ?
              feature.get("features")[0].get("siteData").place : size + "",
            font: "14px Microsoft YaHei",
            fill: new Fill({
              color: "#fff",
            }),
            textBaseline: "bottom",
            offsetY: -10,
            stroke: new Stroke({
              color: "#005DF9",
              width: 4,
            }),
          }),
        });
      },
      zIndex: Infinity,
    });
    map.addLayer(jyfcLayer);
  } else if (type == "gnss") {
    gnssFeatures = featureArr;
    gnssLayer = new VectorLayer({
      source: clusterSource,
      style: function (feature) {
        const size = feature.get("features").length;
        return new Style({
          image: new Icon({
            src: gnssPng,
            scale: 0.5, // 图标大小
          }),
          text: new Text({
            text: size == 1 ?
              feature.get("features")[0].get("siteData").pointName : size + "",
            font: "14px Microsoft YaHei",
            fill: new Fill({
              color: "#fff",
            }),
            textBaseline: "bottom",
            offsetY: -10,
            stroke: new Stroke({
              color: "#EB8300",
              width: 4,
            }),
          }),
        });
      },
      zIndex: Infinity,
    });
    map.addLayer(gnssLayer);
  }
  //大屏页面的图层，图标设置
  else if (type == "jyb") {
    jybFeatures = featureArr;
    jybLayer = new VectorLayer({
      source: vectorSource,
      style: function (feature) {
        return new Style({
          image: new Icon({
            src: type == "jyb" ? jybPng : fcbPng,
            scale: 0.4, // 图标大小
          }),
          // text: new Text({
          //   text: feature.get("siteData").place,
          //   font: "14px Microsoft YaHei",
          //   fill: new Fill({
          //     color: "#fff",
          //   }),
          //   textBaseline: "bottom",
          //   offsetY: -10,
          //   stroke: new Stroke({
          //     color: "#81E14F",
          //     width: 4,
          //   }),
          // }),
        });
      },
      zIndex: Infinity,
    });
    map.addLayer(jybLayer);
  } else if (type == "fcb") {
    fcbFeatures = featureArr;
    fcbLayer = new VectorLayer({
      source: vectorSource,
      style: function (feature) {
        return new Style({
          image: new Icon({
            src: type == "fcb" ? fcbPng : jybPng,
            scale: 0.4, // 图标大小
          }),
          // text: new Text({
          //   text: feature.get("siteData").place,
          //   font: "14px Microsoft YaHei",
          //   fill: new Fill({
          //     color: "#fff",
          //   }),
          //   textBaseline: "bottom",
          //   offsetY: -10,
          //   stroke: new Stroke({
          //     color: "#81E14F",
          //     width: 4,
          //   }),
          // }),
        });
      },
      zIndex: Infinity,
    });
    map.addLayer(fcbLayer);
  } else if (type == "gnss2") {
    gnss2Features = featureArr;
    gnss2Layer = new VectorLayer({
      source: vectorSource,
      style: function (feature) {
        return new Style({
          image: new Icon({
            src: GNSS2,
            scale: 0.4, // 图标大小
          }),
          // text: new Text({
          //   text: feature.get("siteData").pointName,
          //   font: "14px Microsoft YaHei",
          //   fill: new Fill({
          //     color: "#fff",
          //   }),
          //   textBaseline: "bottom",
          //   offsetY: -10,
          //   stroke: new Stroke({
          //     color: "#1DB1ED",
          //     width: 4,
          //   }),
          // }),
        });
      },
      zIndex: Infinity,
    });
    map.addLayer(gnss2Layer);
  }
}
/* 
移除图层文字样式
*/
export function removeTextLayer(layer, type) {
  layer.setStyle(function (feature) {
    return new Style({
      image: new Icon({
        src: type == "jyb" ? jybPng : type == "fcb" ? fcbPng : GNSS2,
        scale: 0.4, // 图标大小
      }),
      // 不包含text样式，去掉文字
    });
  });
}
/* 
恢复图层文字样式
*/
export function recoverTextLayer(layer, type) {
  layer.setStyle(function (feature) {
    if (type == "gnss2") {
      return new Style({
        image: new Icon({
          src: GNSS2,
          scale: 0.4, // 图标大小
        }),
      });
    } else {
      return new Style({
        image: new Icon({
          src: type == "fcb" ? fcbPng : jybPng,
          scale: 0.4, // 图标大小
        }),
      });
    }
  });
}

/**
 * 天地图影像图层加载
 */
export function addTiandituImg() {
  const cp = commonParam();
  // 影像图层
  let stilesLayer = new TileLayer({
    source: new WMTS({
      url: "http://t{1-7}.tianditu.gov.cn/img_w/wmts?tk=" + TDKEY,
      layer: "img",
      matrixSet: "w",
      format: "tiles",
      projection: cp.projection,
      tileGrid: new WMTSTileGrid({
        origin: getTopLeft(cp.projectionExtent),
        resolutions: cp.resolutions,
        matrixIds: cp.matrixIds,
      }),
      style: "default",
      wrapX: true,
      crossOrigin: "anonymous",
    }),
  });
  return stilesLayer;
}

/**
 * 加载高德在线服务
 * @returns tileLayers
 */
export function addAutoMap() {
  return new TileLayer({
    preload: Infinity,
    source: new XYZSource({
      projection: gcj02Mecator,
      url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}",
      crossOrigin: "anonymous",
      maxZoom: 16,
      wrapX: false,
    }),
    zIndex: 0,
  });
}

/**
 * 加载高德在线注记服务
 * @returns tileLayers
 */
export function addAutoLabelMap() {
  return new TileLayer({
    preload: Infinity,
    source: new XYZSource({
      projection: gcj02Mecator,
      url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8",
      crossOrigin: "anonymous",
      maxZoom: 16,
      wrapX: false,
    }),
    visible: false
  });
}


/**
 * 海图图层加载
 */
export function addSeaImg() {
  return new TileLayer({
    source: new TileWMS({
      url: `${EV_SERVER}earthview/rest/services/chartserver/wms?`,
      params: {
        LAYERS: "C110408A",
        VERSION: "1.1.0",
        STYLES: "All,DayTime,Tradition,FiveMeter,Chinese",
        TRANSPARENT: true, //
        CRS: "EPSG:900913",
        SERVICE: "WMS",
      },
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      // projection: cpp.projection,
      // crossOrigin: "anonymous",
    }),
  });
}
/**
 * 天地图注记加载--XYZ方式
 */
export function addTiandituLabel() {
  // 矢量
  let labelsLayer = new TileLayer({
    source: new XYZSource({
      url: "http://t{1-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=" +
        TDKEY,
      wrapX: false,
      crossOrigin: "anonymous",
    }),
  });
  return labelsLayer;
}
/*
 *添加江苏边界
 */
export function addJSBorder() {
  // 创建江苏省边界
  const vectorSource = new VectorSource({
    format: new GeoJSON(),
    features: new GeoJSON({
      featureProjection: "EPSG:3857",
    }).readFeatures(jiangSu),
  });
  return new VectorLayer({
    source: vectorSource,
    zIndex: 0,
    style: new Style({
      fill: null,
      //边线颜色
      stroke: new Stroke({
        color: "#D1D3A0",
        width: 5,
      }),
    }),
  });
}

/*
 *添加江苏所有市边界
 */
//  export function addJSShiBorder() {
//   // 创建江苏省边界
//   const vectorSource = new VectorSource({
//     format: new GeoJSON(),
//     features: new GeoJSON({
//       featureProjection: "EPSG:4326",
//     }).readFeatures(shi),
//   });
//   return new VectorLayer({
//     source: vectorSource,
//     zIndex: 2,
//     style: new Style({
//       fill: null,
//       //边线颜色
//       stroke: new Stroke({
//         color: "#00ff00",
//         width: 5,
//       }),
//     }),
//   });
// }
/**
 * 江苏在线影像图层加载
 * @returns 苏州影像图层
 */
export function addJSOnlineLayer() {
  let cpp = commonParamOf4490();
  const wmsLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geowebcache/service/wms?",
      params: {
        LAYERS: "Image2022",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
        REQUEST: "GetMap",
      },
      //远程WMS服务器的类型
      // serverType: "geowebcache",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 注记
  const zjLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geowebcache/service/wms?",
      params: {
        LAYERS: "2018zj",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geowebcache",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 省边界
  const shengLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "province_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 市边界
  const shiLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "city_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 县边界
  const xianLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "county_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });

  return [wmsLayer, zjLayer, shiLayer, shengLayer];
}

var insarShpClickEvent = null; //矢量图层点击事件
var insarShpContextmenuEvent = null; //矢量图层右键点击事件
var insarCurFeature = null; //点击高亮的shp图层
var curVectorLayerArr = []; //当前矢量图层数组
var ckHandler = null;
var ckPos = null;
var echartXrr = null;
var echartYrr = null;
var insarLayer = null; //insar图层
var insarOverlay = null;
var insarMonitorkeyDown = false;
// 绘制上传矢量的基础样式
const baseStyle = new Style({
  fill: new Fill({
    color: "#ffffff",
  }),
  //边线颜色
  stroke: new Stroke({
    color: "#FF0000",
    width: 2,
  }),
  image: new Circle({
    radius: 7,
    fill: new Fill({
      color: "green",
    }),
  }),
});
// 矢量点选高亮时的样式
const clickStyle = new Style({
  fill: new Fill({
    color: "#409eff30",
  }),
  stroke: new Stroke({
    color: "#409eff",
    width: 2,
  }),
  image: new Circle({
    radius: 10,
    stroke: new Stroke({
      color: "rgba(0,0,0,0.7)",
    }),
    fill: new Fill({
      color: "#00FF40",
    }),
  }),
});

/**
 * 加载geoserver mbtiles服务
 * @param {*} style
 * @param {*} layerName
 * @param {*} tilesOrigin
 * @returns tileLayers
 */
export function addMbTiles(style, layerName, tilesOrigin) {
  return new TileLayer({
    zIndex: 100,
    source: new TileWMS({
      url: "/geoserver/js/wms",
      params: {
        VERSION: "1.1.1",
        tiled: true,
        STYLES: style,
        LAYERS: layerName,
        exceptions: "application/vnd.ogc.se_inimage",
        tilesOrigin: tilesOrigin,
      },
      // serverType: "geoserver",
      crossOrigin: "anonymous",
    }),
  });
}
/*
 *添加insar图层
 */
export function addInsarLayer(xLayers) {
  const layers = [];
  for (let i in xLayers) {
    const xli = xLayers[i];
    layers.push(addMbTiles(xli.style, xli.layers, xli.tilesOrigin));
  }
  insarLayer = new LayerGroup({
    layers: layers,
  });
  map.addLayer(insarLayer);
  startInsarMonitorClick();
}
export function initClickOverlay() {
  // 样本点选弹框
  const container = document.getElementById("popup");
  const closer = document.getElementById("popupCloser");
  insarOverlay = new Overlay({
    element: container,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    // offset: [-250, -3],
    offset: [0, 0],
    autoPanMargin: 100,
  });
  closer.onclick = () => {
    insarOverlay.setPosition(undefined);
    closer.blur();
    return false;
  };
  map.addOverlay(insarOverlay);
}
/*
 *移除insar图层
 */
export function removeInsarLayer() {
  map.removeLayer(insarLayer);
  endInsarMonitorClick();
}
/*
 *更新insar图层
 */
export function updateInsarLayer(styleName) {
  insarLayer.values_.layers.array_ &&
    insarLayer.values_.layers.array_.map((jsInSARLayer) => {
      jsInSARLayer.getSource().updateParams({
        STYLES: styleName,
      });
    });
}

// 绘制上传数据
export function drawUploadGeojson(geojsonData, id) {
  // 创建一个VectorSource实例，并使用GeoJSON数据
  const vectorSource = new VectorSource({
    format: new GeoJSON(),
    // 使用上面的GeoJSON数据对象
    features: new GeoJSON({
      featureProjection: "EPSG:3857",
    }).readFeatures(geojsonData),
  });
  // 创建VectorLayer并将VectorSource添加到该层
  const vectorLayer = new VectorLayer({
    source: vectorSource,
    zIndex: curVectorLayerArr.length + 1,
    name: "upload",
    id,
    style: baseStyle,
  });
  map.addLayer(vectorLayer);
  const [minX, minY, maxX, maxY] = [0, 0, 1068, 653];
  const padding = [minY + 160, 1068 - maxX, 717 - maxY + 160, minX];
  map.getView().fit(vectorLayer.getSource().getExtent(), {
    padding,
    duration: 1000,
  });
  curVectorLayerArr.push({
    uid: id,
    layer: vectorLayer,
  });
}

// 设置上传的矢量图层层级
export function setCurVectorLayerArrZIndex(file, index) {
  curVectorLayerArr
    .filter((layer) => file.uid == layer.uid)[0]
    .layer.setZIndex(index + 1);
}
// 移除上传指定矢量图层
export function removeCurVectorLayer(file) {
  map.removeLayer(
    curVectorLayerArr.filter((layer) => file.uid == layer.uid)[0].layer
  );
}
/**
 * 关闭点击矢量获取数据事件
 */
export function closeClickShpData() {
  unByKey(insarShpClickEvent);
  unByKey(insarShpContextmenuEvent);
  insarShpClickEvent = null;
  insarShpContextmenuEvent = null;
  const container = document.getElementById("shpDataPopup");
  container.style.display = "none";
}
/**
 * 关闭点选弹框
 */
export function closePopup() {
  const container = document.getElementById("shpDataPopup");
  container.style.display = "none";
}

/**
 * 打开点击矢量获取数据事件
 */
export function clickShpData(callback) {
  //点击上传的shp事件
  const container = document.getElementById("shpDataPopup");
  // 监听地图的 click 事件
  insarShpClickEvent = map.on("click", (event) => {
    if (insarCurFeature) insarCurFeature.setStyle(baseStyle);
    event.stopPropagation();
    let showFlag = false;
    // 通过地图和视图获取点击的像素坐标
    const pixel = map.getEventPixel(event.originalEvent);
    const coordinate = map.getCoordinateFromPixel(pixel);
    // 查询该像素下的所有要素
    map.forEachFeatureAtPixel(pixel, (feature, layer) => {
      // 确保要素来自矢量图层
      if (
        layer instanceof VectorLayer &&
        layer.values_.name == "upload" &&
        !showFlag
      ) {
        insarCurFeature = feature;
        // 点击位置要素高亮显示
        feature.setStyle(clickStyle);
        showFlag = true;
        // 获取并显示要素的数据
        const data = feature.getProperties();
        // 显示弹窗
        if (data) {
          delete data.geometry;
          callback(data);
          container.style.display = "block";
          let Overlay = map.getOverlayById("shpDataPopup");
          Overlay.setPosition(coordinate);
        }
      }
    });
    if (!showFlag) {
      const container = document.getElementById("shpDataPopup");
      container.style.display = "none";
    }
  });

  // 右键点击事件
  const rightContainer = document.getElementById("shpSetPopup");
  // 为地图添加右击事件监听
  insarShpContextmenuEvent = map.on("contextmenu", function (event) {
    // 阻止默认的右键菜单出现
    event.preventDefault();
    event.stopPropagation();
    // 获取右击的坐标
    let showFlag = false;
    // 通过地图和视图获取点击的像素坐标
    const pixel = map.getEventPixel(event.originalEvent);
    const coordinate = map.getCoordinateFromPixel(pixel);
    // 查询该像素下的所有要素
    map.forEachFeatureAtPixel(pixel, function (feature, layer) {
      // 确保要素来自矢量图层
      if (
        layer instanceof VectorLayer &&
        layer.values_.name == "upload" &&
        !showFlag
      ) {
        showFlag = true;
        // 显示弹窗
        shpLayer.value = layer;
        rightContainer.style.display = "block";
        let Overlay = map.getOverlayById("shpSetPopup");
        Overlay.setPosition(coordinate);
      }
    });
    if (!showFlag) {
      const rightContainer = document.getElementById("shpSetPopup");
      rightContainer.style.display = "none";
    }
  });
}

// 初始化insar监测界面overlay
export function initOverlay() {
  // 矢量数据弹框
  const shpContainer = document.getElementById("shpDataPopup");
  const shpCloser = document.getElementById("shpDataPopupCloser");
  let shpOverlay = new Overlay({
    id: "shpDataPopup",
    element: shpContainer,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    // offset: [-250, -3],
    offset: [0, 0],
    autoPanMargin: 100,
  });
  shpCloser.onclick = () => {
    shpOverlay.setPosition(undefined);
    shpCloser.blur();
    return false;
  };
  map.addOverlay(shpOverlay);

  // 矢量设置弹框
  const shpSetContainer = document.getElementById("shpSetPopup");
  const shpSetCloser = document.getElementById("shpSetPopupCloser");
  let shpSetOverlay = new Overlay({
    id: "shpSetPopup",
    element: shpSetContainer,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    // offset: [-250, -3],
    offset: [0, 0],
    autoPanMargin: 100,
  });
  shpSetCloser.onclick = () => {
    shpSetOverlay.setPosition(undefined);
    shpSetCloser.blur();
    return false;
  };
  map.addOverlay(shpSetOverlay);

  // 样本点选弹框
  const container = document.getElementById("popup");
  const closer = document.getElementById("popupCloser");
  insarOverlay = new Overlay({
    element: container,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    // offset: [-250, -3],
    offset: [0, 0],
    autoPanMargin: 100,
  });
  closer.onclick = () => {
    insarOverlay.setPosition(undefined);
    closer.blur();
    return false;
  };
  map.addOverlay(insarOverlay);

  //  对比弹框
  const containerDiff = document.getElementById("popupDiff");
  const closerDiff = document.getElementById("popupCloserDiff");

  insarOverlayDiff = new Overlay({
    element: containerDiff,
    autoPan: true,
    autoPanAnimation: {
      duration: 250,
    },
    // offset: [-250, -3],
    offset: [0, 0],
    autoPanMargin: 100,
  });
  closerDiff.onclick = () => {
    insarOverlayDiff.setPosition(undefined);
    closerDiff.blur();
    return false;
  };
  map.addOverlay(insarOverlayDiff);
}

/*
 * 绘制折线图
 */
function echartShow(rfp) {
  let xArr = [],
    yArr = [];
  for (let key in rfp) {
    xArr.push(key.split("_")[1]);
    yArr.push(rfp[key]);
  }
  echartXrr = xArr;
  echartYrr = yArr;
  let chartDom = document.getElementById("xlEcharts");
  let myCharts = echarts.init(chartDom);
  let option = {
    grid: {
      left: "7%",
      right: "5%",
      top: "40",
      containLabel: true,
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "none",
      },
    },
    xAxis: {
      type: "category",
      data: xArr,
      axisLabel: {
        color: "#fff",
      },
      axisLine: {
        //x轴线的颜色以及宽度
        show: true,
        lineStyle: {
          width: 0,
          type: "solid",
        },
        onZero: false,
      },
      axisTick: {
        inside: true,
      },
    },
    yAxis: {
      name: curLayerType.value == "js_xl" ? "单位（mm）" : "单位（mm/a）",
      type: "value",
      axisLabel: {
        color: "#fff",
      },
      splitLine: {
        lineStyle: {
          color: ["#ffffff10"],
          width: 1,
          type: "dashed",
        },
      },
      nameTextStyle: {
        color: "#fff",
        fontSize: 15,
      },
    },
    series: [{
      data: yArr,
      type: "line",
      smooth: true,
      showSymbol: false,
      lineStyle: {
        width: 2,
        color: "#33D1C9",
        type: "dashed",
      },
      areaStyle: {
        //前四个参数代表位置 左下右上，暗青色到亮青色，
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
            offset: 0,
            color: "rgba(51, 209, 201, 0.6)",
          },
          {
            offset: 1,
            color: "rgba(1, 191, 236,0)",
          },
        ]),
      },
      emphasis: {
        focus: "series",
      },
      markPoint: {
        itemStyle: {
          color: "#33D1C9",
        },
        label: {
          color: "#fff",
        },
        data: [{
            type: "max",
            name: "Max",
            label: {
              formatter: (params) => {
                return params.value.toFixed(1) + "";
              },
            },
          },
          {
            type: "min",
            name: "Min",
            label: {
              formatter: (params) => {
                return params.value.toFixed(1) + "";
              },
            },
          },
        ],
      },
    }, ],
    dataZoom: [
      //1.横向使用滚动条
      {
        type: "slider", //有单独的滑动条，用户在滑动条上进行缩放或漫游。inside是直接可以是在内部拖动显示
        show: true, //是否显示 组件。如果设置为 false，不会显示，但是数据过滤的功能还存在。
        start: 0, //数据窗口范围的起始百分比0-100
        // end: 10, //数据窗口范围的结束百分比0-100
        xAxisIndex: [0], // 此处表示控制第一个xAxis，设置 dataZoom-slider 组件控制的 x轴 可是已数组[0,2]表示控制第一，三个；xAxisIndex: 2 ，表示控制第二个。yAxisIndex属性同理
        // showDetail: false,//即拖拽时候是否显示详细数值信息 默认true
        // bottom: -10, //距离底部的距离
        backgroundColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
            offset: 0,
            color: "rgba(51, 209, 201, 0.6)",
          },
          {
            offset: 1,
            color: "rgba(1, 191, 236,0)",
          },
        ]), //组件的背景颜色
        fillerColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
            offset: 0,
            color: "#00D5FF",
          },
          {
            offset: 1,
            color: "#0084FF",
          },
        ]), //选中范围的填充颜色
        borderColor: "#0084FF", //边框颜色
      },
    ],
  };
  myCharts && myCharts.setOption(option);
}

/*
 * 导出表格
 */
export function tableToExcel() {
  // 用,隔开，一个逗号就是一个单元格
  let str = "时间,Z值,坐标\n";
  //处理表格导出需要的数据
  let echartsData = echartXrr.map((i, j) => ({
    date: i,
    name: echartYrr[j],
    pos: ckPos,
  }));
  //遍历生成数据
  for (let i = 0; i < echartsData.length; i++) {
    for (const key in echartsData[i]) {
      str += `${echartsData[i][key] + "\t"},`;
    }
    str += "\n";
  }
  //防止中文乱码
  const uri = "data:text/csv;charset=utf-8,\ufeff" + encodeURIComponent(str);
  const link = document.createElement("a");
  link.href = uri;
  // 对下载的文件命名
  link.download = `沉降信息.xlsx`;
  link.click();
}
/*
 * 开启insar监测的点击事件
 */
function startInsarMonitorClick() {
  const container = document.getElementById("popup");
  const olContent = document.getElementById("popupContent");
  ckHandler = (evt) => {
    if (exportImgStatus.value) return;
    const coordinate = evt.coordinate;
    const pos = transform(coordinate, "EPSG:3857", "EPSG:4326");
    ckPos = `Point(${pos[0]} ${pos[1]})`;
    const viewResolution = viewer.getResolution();
    const lsArr = insarLayer.values_.layers.array_;
    lsArr.map((jsInSARLayer) => {
      const url = jsInSARLayer
        .getSource()
        .getFeatureInfoUrl(coordinate, viewResolution, "EPSG:3857", {
          INFO_FORMAT: "application/json",
        });
      if (url) {
        fetch(url)
          .then((response) => response.json())
          .then((res) => {
            const rf = res.features;
            if (rf.length > 0) {
              const rfp = rf[0].properties;
              if (rfp.hasOwnProperty("layer"))
                Reflect.deleteProperty(rfp, "layer");
              if (rfp.hasOwnProperty("path"))
                Reflect.deleteProperty(rfp, "path");
              container.style.display = "block";
              olContent.innerHTML =
                "<div id='xlEcharts' style='width:550px;height:280px;margin-left:20px;margin-top:57px;' ></div>";
              echartShow(rfp);
              insarOverlay.setPosition(coordinate);
            }
          });
      }
    });
  };

  map.on("singleclick", ckHandler);
}
/*
 * 关闭insar监测的点击事件
 */
export function endInsarMonitorClick() {
  const container = document.getElementById("popup");
  ckHandler && map.un("singleclick", ckHandler);
  ckHandler = null;
  if (container) container.style.display = "none";
  ckPos = null;
}
/*
 * 控制insar监测点选开启关闭
 */
export function controlClickEvent() {
  document.onkeydown = (e) => {
    const keyNum = window.event ? e.keyCode : e.which;
    if (keyNum === "C".charCodeAt(0)) {
      insarMonitorkeyDown = !insarMonitorkeyDown;
      if (insarMonitorkeyDown) {
        ElMessage({
          message: "开启点选查询",
          grouping: true,
          type: "success",
        });
        if (insarLayer) {
          startInsarMonitorClick();
        }
        if (insarDiffLayer) {
          startInsarDiffClick();
        }
      } else {
        ElMessage({
          message: "关闭点选查询",
          grouping: true,
          type: "warning",
        });
        if (ckHandler) {
          endInsarMonitorClick();
        }
        if (ckHandlerDiff) {
          endInsarDiffClick();
        }
      }
    }
  };
}

var dzxLayer = null; //等值线图层
var dzxBorderLayer = null; //等值线外围边界图层
var insarDraw = null;
var insarDarwSource = new VectorSource();
var insarDrawLayer = null;
var insarPointerOverFeature = null; //当前悬浮的feature
var isnarMapMoveEvent = null; //鼠标移动事件
var insarMapClickEvent = null; //鼠标点击事件
var insarMaskLayer = null; //遮罩图层
var inasrSelVectorLayer = null; //点击的矢量图层
var insarFatherAreaCode = []; //父级行政区划编号
var insarCurAreaLevel = -1; //当前点击的行政区划等级

/**
 * 根据范围进行缩放显示
 * @param {*} map 底图
 * @param {*} extent 四至
 */
function zoomToExtent(map, extent) {
  const [minX, minY, maxX, maxY] = [0, 0, 1068, 653];
  const padding = [minY + 16, 1068 - maxX, 717 - maxY + 16, minX];
  map.getView().fit(extent, {
    padding,
    duration: 1000,
  });
}

/*
 *初始化绘制图层
 */
export function initInsarDrawLayer() {
  insarDrawLayer = new VectorLayer({
    source: insarDarwSource,
    style: new Style({
      stroke: new Stroke({
        color: "#ff0000",
        width: 4,
      }),
    }),
    zIndex: Infinity,
  });
  map.addLayer(insarDrawLayer);
}

/**
 * 移除绘制图层的显示
 */
export function removeDrawLayer() {
  insarDarwSource.clear();
  map.removeInteraction(insarDraw);
  insarDraw = null;
}

/*
 * 添加等值线图层
 */
export function addDzxLayer(layerName, style) {
  dzxLayer = new TileLayer({
    zIndex: Infinity,
    source: new TileWMS({
      url: `/geoserver/js/wms?`,
      params: {
        VERSION: "1.1.1",
        tiled: true,
        LAYERS: layerName,
        exceptions: "application/vnd.ogc.se_inimage",
        STYLES: style,
      },
      crossOrigin: "anonymous",
    }),
  });
  map.addLayer(dzxLayer);
}

/*
 * 删除等值线图层
 */
export function removeDzxLayer() {
  map.removeLayer(dzxLayer);
  dzxLayer = null;
}

/**
 * 清除shp图层以及点击事件
 */
export function clearVectorLayer() {
  if (curVectorLayer) {
    map.removeLayer(curVectorLayer);
  }
}
/**
 * 绘制矩形
 * @param {*} callback
 */
export function drawCirclePl(callback) {
  insarDraw = new Draw({
    source: insarDarwSource,
    type: "Circle",
    geometryFunction: createBox(),
    style: new Style({
      stroke: new Stroke({
        color: "#ff0000",
        width: 4,
      }),
    }),
  });
  insarDraw.on("drawstart", () => {
    insarDarwSource.clear();
  });
  insarDraw.on("drawend", (evt) => {
    let extent = evt.feature.getGeometry().getExtent();
    zoomToExtent(map, extent);
    callback(extent);
  });
  map.addInteraction(insarDraw);
}
/**
 * 绘制江苏遮罩
 */
export function drawMask() {
  addDivision(320000); //320000江苏省行政区划编号
}

/**
 * 清除江苏遮罩
 */
export function clearMask() {
  map.removeLayer(inasrSelVectorLayer);
  map.removeLayer(insarMaskLayer);
  inasrSelVectorLayer = null;
  insarMaskLayer = null;
}
/**
 * 关闭地图鼠标悬浮事件
 */
export function closePointermove() {
  unByKey(isnarMapMoveEvent);
  unByKey(insarMapClickEvent);
  isnarMapMoveEvent = null;
  insarMapClickEvent = null;
}

/**
 * 添加行政区划
 */
export async function addDivision(areaCode) {
  if (areaCode < 0) {
    if (insarFatherAreaCode.length == 1) {
      return;
    }
    // 返回上一级
    insarCurAreaLevel += -1;
    insarFatherAreaCode.pop();
  } else {
    // 下一级
    insarCurAreaLevel += 1;
    insarFatherAreaCode.push(areaCode);
  }
  if (insarMaskLayer) {
    map.removeLayer(insarMaskLayer);
  }
  let {
    data
  } = await getArea(insarFatherAreaCode[insarCurAreaLevel]);
  if (data.code == 200) {
    let result = data.data;
    let fatherGeojson = {
      type: "FeatureCollection",
      features: [{
        type: "Feature",
        properties: {
          name: result.areaName,
          adcode: result.areaCode,
        },
        geometry: WKT.parse(result.geom),
      }, ],
    };
    selAreaWKTObj.value = result.geom;
    // 创建父级边界
    const maskVectorSource = new VectorSource({
      format: new GeoJSON(),
      features: new GeoJSON({
        featureProjection: "EPSG:3857",
      }).readFeatures(fatherGeojson),
    });
    insarMaskLayer = new VectorLayer({
      source: maskVectorSource,
      zIndex: Infinity,
    });
    map.addLayer(insarMaskLayer);
    // 创建选中图层
    if (inasrSelVectorLayer) {
      map.removeLayer(inasrSelVectorLayer);
      inasrSelVectorLayer = null;
    }
    let childGeojson = {
      type: "FeatureCollection",
      features: result.children.map((a) => {
        return {
          type: "Feature",
          properties: {
            name: a.areaName,
            adcode: a.areaCode,
          },
          geometry: WKT.parse(a.geom),
        };
      }),
    };
    // 创建子级边界
    const vectorSource = new VectorSource({
      format: new GeoJSON(),
      // 使用上面的GeoJSON数据对象
      features: new GeoJSON({
        featureProjection: "EPSG:3857",
      }).readFeatures(childGeojson),
    });
    // 创建VectorLayer并将VectorSource添加到该层
    inasrSelVectorLayer = new VectorLayer({
      source: vectorSource,
      zIndex: Infinity,
      name: "clickLayer",
    });
    map.addLayer(inasrSelVectorLayer);
    zoomToExtent(map, insarMaskLayer.getSource().getExtent());
  }
}

/**
 * 开启地图鼠标悬浮事件、点击事件
 */
export function openPointermove() {
  // 监听地图的 click 事件
  insarMapClickEvent = map.on("click", (event) => {
    let flag = false;
    // 通过地图和视图获取点击的像素坐标
    const pixel = map.getEventPixel(event.originalEvent);
    // 查询该像素下的所有要素
    map.forEachFeatureAtPixel(pixel, (feature, layer) => {
      flag = true;
      // 确保要素来自矢量图层
      const data = feature.getProperties();
      if (layer instanceof VectorLayer && data.adcode && layer.values_.name) {
        // 获取并显示要素的数据
        addDivision(data.adcode);
        // 在这里你可以处理数据，比如显示弹窗等
      }
    });
    // 点击空白区域
    if (!flag) {
      // 绘制父级边界
      addDivision(-1);
    }
  });
  // 地图悬浮事件
  isnarMapMoveEvent = map.on("pointermove", (evt) => {
    if (!insarMaskLayer) return;
    // 判断鼠标是否在图层范围内
    let maskfeatures = insarMaskLayer.get("source").getFeatures();
    for (let j = 0; j < maskfeatures.length; j++) {
      let polygonGeometry = maskfeatures[j].getGeometry();
      if (polygonGeometry.intersectsCoordinate(evt.coordinate)) {
        map.getTargetElement().style.cursor = "pointer";
      } else {
        map.getTargetElement().style.cursor = "default";
      }
    }
    // 修改悬浮区域feature样式
    const featureOver = map.forEachFeatureAtPixel(evt.pixel, (feature) => {
      // 鼠标移入时触发
      feature.setStyle(
        new Style({
          //填充色
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.2)",
          }),
          //边线颜色
          stroke: new Stroke({
            color: "#FF0000",
            width: 4,
          }),
          text: new Text({
            // 位置
            textAlign: "center",
            // 基准线
            textBaseline: "middle",
            // 文字样式
            font: "bold 18px 微软雅黑",
            // 文本内容
            text: `${feature.get("name") ? feature.get("name") : ""}`,
            // 文字颜色
            fill: new Fill({
              color: "#FF0000",
            }),
            // 文字背景
            // stroke: new Stroke({ color: "#353535", width: 1 }),
          }),
          //点样式,继承image
          image: new Circle({
            radius: 7,
            fill: new Fill({
              color: "#ffcc33",
            }),
          }),
        })
      );
      return feature;
    });
    // 鼠标移出时触发
    if (insarPointerOverFeature && insarPointerOverFeature != featureOver) {
      insarPointerOverFeature.setStyle();
    }
    insarPointerOverFeature = featureOver;
  });
}

var insarDiffLayer = null; //差异对比图层
var insarOverlayDiff = null;
var ckHandlerDiff = null;
/**
 * 加载geoserver WMTS服务
 * @param {*} layer 图层名称
 * @param {*} style 样式
 * @returnstileLayers
 */
export function addDiffLayer(layer, style) {
  insarDiffLayer && map.removeLayer(insarDiffLayer);
  const gridNames = [
    "EPSG:4326:0",
    "EPSG:4326:1",
    "EPSG:4326:2",
    "EPSG:4326:3",
    "EPSG:4326:4",
    "EPSG:4326:5",
    "EPSG:4326:6",
    "EPSG:4326:7",
    "EPSG:4326:8",
    "EPSG:4326:9",
    "EPSG:4326:10",
    "EPSG:4326:11",
    "EPSG:4326:12",
    "EPSG:4326:13",
    "EPSG:4326:14",
    "EPSG:4326:15",
    "EPSG:4326:16",
    "EPSG:4326:17",
    "EPSG:4326:18",
    "EPSG:4326:19",
    "EPSG:4326:20",
    "EPSG:4326:21",
  ];
  //切片大小
  const resolutions = [
    0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625,
    0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625,
    6.866455078125e-4, 3.4332275390625e-4, 1.71661376953125e-4,
    8.58306884765625e-5, 4.291534423828125e-5, 2.1457672119140625e-5,
    1.0728836059570312e-5, 5.364418029785156e-6, 2.682209014892578e-6,
    1.341104507446289e-6, 6.705522537231445e-7, 3.3527612686157227e-7,
  ];
  //设置地图投影
  const projection = new Projection({
    code: "EPSG:4326", //投影编码
    units: "degrees",
    axisOrientation: "neu",
  });
  insarDiffLayer = new TileLayer({
    source: new WMTS({
      url: "/geoserver/gwc/service/wmts?",
      layer: layer,
      style: style,
      matrixSet: "EPSG:4326",
      format: "image/png",
      projection: projection,
      //切片信息
      tileGrid: new WMTSTileGrid({
        tileSize: [256, 256],
        extent: [-180.0, -90.0, 180.0, 90.0], //范围
        origin: [-180.0, 90.0],
        resolutions: resolutions,
        matrixIds: gridNames,
      }),
      //
      wrapX: false,
      crossOrigin: "anonymous",
    }),
  });
  map.addLayer(insarDiffLayer);
}
export function removeDiffLayer() {
  insarDiffLayer && map.removeLayer(insarDiffLayer);
}

function startInsarDiffClick() {
  const containerDiff = document.getElementById("popupDiff");
  const olContentDiff = document.getElementById("popupContentDiff");
  ckHandlerDiff = (evt) => {
    const coordinate = evt.coordinate;
    const pos = transform(coordinate, "EPSG:3857", "EPSG:4326");
    let wktPoint = `POINT (${pos[0]} ${pos[1]})`;
    getPoiMsg(wktPoint).then((res) => {
      if (res.data.code === 200) {
        if (res.data.data.length == 0) return false;
        const posMsg = res.data.data[0].z;
        containerDiff.style.display = "block";
        olContentDiff.innerHTML =
          "<div  style='line-height:30px;'>" + "沉降差值:" + posMsg + "</div>";
        insarOverlayDiff.setPosition(coordinate);
      }
    });
  };
  map.on("singleclick", ckHandlerDiff);
}
/*
 * 关闭insar 差异对比图层的点击事件
 */
function endInsarDiffClick() {
  const containerDiff = document.getElementById("popupDiff");
  map.un("singleclick", ckHandlerDiff);
  ckHandlerDiff = null;
  containerDiff.style.display = "none";
}

/*******************insar数据对比*********************/
let compareView = null; //cpView
let baseMap = null;
let mapList = [];
/**
 * 苏州影像图层加载
 * @returns 苏州影像图层
 */
function addJSTileLayer() {
  let cpp = commonParamOf4490();
  const wmsLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geowebcache/service/wms?",
      params: {
        LAYERS: "Image2022",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
        REQUEST: "GetMap",
      },
      //远程WMS服务器的类型
      // serverType: "geowebcache",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  const zjLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geowebcache/service/wms?",
      params: {
        LAYERS: "2018zj",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geowebcache",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 市边界
  const shiLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "city_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 县边界
  const xianLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "county_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  // 省边界
  const shengLayer = new TileLayer({
    zIndex: 0,
    source: new TileWMS({
      url: "http://dxjc.efgd.net:8084/geologicalMap/geoserver/division/wms?",
      params: {
        LAYERS: "province_line",
        VERSION: "1.1.0",
        TRANSPARENT: true, //
        CRS: "EPSG:4490",
        SERVICE: "WMS",
        SRS: "EPSG:4490",
      },
      //远程WMS服务器的类型
      // serverType: "geoserver",
      // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡，设置transition为: 0
      transition: 0,
      projection: cpp.projection,
      crossOrigin: "anonymous",
    }),
  });
  return [wmsLayer, zjLayer, shiLayer, shengLayer];
}
/*
 * 创建对比地图
 */
export function createCpMap() {
  compareView = new View({
    center: [12526372.643240804, 4561717.652635764],
    zoom: 4,
    minZoom: 1,
    extent: transformExtent(
      [113.186641, 30.654249, 125.827137, 35.199202],
      "EPSG:4326",
      "EPSG:3857"
    ),
  });
  baseMap = new Map({
    target: "baseMapDom",
    view: compareView,
    controls: [],
    interactions: defaultInteractions({
      altShiftDragRotate: false,
      keyboard: false,
    }),
    layers: [...addJSTileLayer()],
  });
  mapList.push(baseMap);
}

function addXLLayer(xLayers) {
  const layers = [];
  for (let i in xLayers) {
    const xli = xLayers[i];
    layers.push(addMbTiles(xli.style, xli.layers, xli.tilesOrigin));
  }
  return new LayerGroup({
    layers: layers,
  });
}

/*
 * 添加新地图
 */
export function addNewMap(menusType, domId, style) {
  let xLayers = [];
  if (menusType === "js_xl") {
    xLayers = [{
        layers: "js:xlLayer01_1",
        tilesOrigin: 12953091.866186958 + "," + 4038787.5043890662,
        style: style,
      },
      {
        layers: "js:xlLayer01_2",
        tilesOrigin: 13044930.89136937 + "," + 3932314.545820052,
        style: style,
      },
      {
        layers: "js:xlLayer02_1",
        tilesOrigin: 13138438.92967725 + "," + 3752283.463891968,
        style: style,
      },
      {
        layers: "js:xlLayer02_2",
        tilesOrigin: 13178513.946362829 + "," + 3720206.9460358857,
        style: style,
      },
      {
        layers: "js:xlLayer03",
        tilesOrigin: 13208570.765474467 + "," + 3663733.5453803875,
        style: style,
      },
      {
        layers: "js:xlLayer04",
        tilesOrigin: 13231947.747221561 + "," + 3663405.97785773,
        style: style,
      },
      {
        layers: "js:xlLayer05",
        tilesOrigin: 13251985.255564352 + "," + 3663463.6530645695,
        style: style,
      },
      {
        layers: "js:xlLayer06",
        tilesOrigin: 13272022.76390714 + "," + 3655873.289434982,
        style: style,
      },
      {
        layers: "js:xlLayer07",
        tilesOrigin: 13292060.38356942 + "," + 3647041.301907354,
        style: style,
      },
      {
        layers: "js:xlLayer08",
        tilesOrigin: 13266709.595931068 + "," + 3651073.3371919743,
        style: style,
      },
      {
        layers: "js:xlLayer09",
        tilesOrigin: 13338814.347063614 + "," + 3655037.9961891463,
        style: style,
      },
      {
        layers: "js:xlLayer10",
        tilesOrigin: 13358851.855406404 + "," + 3681351.209975001,
        style: style,
      },
      {
        layers: "js:xlLayer11",
        tilesOrigin: 13382228.8371535 + "," + 3618095.073967102,
        style: style,
      },
      {
        layers: "js:xlLayer12",
        tilesOrigin: 13405605.818900594 + "," + 3602520.783520508,
        style: style,
      },
      {
        layers: "js:xlLayer13",
        tilesOrigin: 13442341.473501358 + "," + 3629914.9460884235,
        style: style,
      },
    ];
  } else if (menusType === "js_sl") {
    xLayers = [{
      layers: "js:slLayer",
      tilesOrigin: 12953091.866186958 + "," + 3602361.9519554116,
      style: style,
    }, ];
  }
  const cpLayer = addXLLayer(xLayers);
  const newMap = new Map({
    target: domId,
    view: new View({
      center: [10526372.643240804, 4561717.652635764],
      zoom: 2,
      minZoom: 1,
      extent: transformExtent(
        [116.186641, 30.654249, 125.827137, 35.199202],
        "EPSG:4326",
        "EPSG:3857"
      ),
    }),
    controls: [],
    interactions: defaultInteractions({
      altShiftDragRotate: false,
      keyboard: false,
    }),
    layers: [...addJSTileLayer(), cpLayer],
  });
  mapList.push(newMap);
}

export function updateMapList() {
  for (const i of mapList) i.updateSize();
}

export function filterUpdateMapList(layerName) {
  mapList = mapList.filter((i) => {
    return i.values_.target !== layerName;
  });
  for (const i of mapList) i.updateSize();
}

/*
 * 添加专题图层
 */
export function addZtLayer(layerName, styleName) {
  let layer = new TileLayer({
    zIndex: Infinity,
    source: new TileWMS({
      url: `/geoserver/land-subsidence/wms?`,
      params: {
        VERSION: "1.1.1",
        tiled: true,
        LAYERS: layerName,
        exceptions: "application/vnd.ogc.se_inimage",
        STYLES: styleName ? styleName : "",
      },
      crossOrigin: "anonymous",
    }),
  });
  zttLayers.push({
    layerName,
    layer,
  });
  map.addLayer(layer);
  // console.log(zttLayers);
}

/*
 * 删除专题图层
 */
export function removeZtLayer(layerName) {
  map.removeLayer(zttLayers.find((a) => a.layerName == layerName).layer);
  zttLayers = zttLayers.filter((a) => a.layerName !== layerName);
  // console.log(zttLayers);
}

/**
 * 通过图层名称获取图层
 * @param {String}
 * @returns {Layer}
 */
function getLayerByName(name) {
  let allLayers = map.getLayers().getArray();
  let layer = undefined;
  if (allLayers.length) {
    for (let i = 0; i < allLayers.length; i++) {
      if (allLayers[i].get('name') === name) {
        layer = allLayers[i];
        break;
      }
    }
  }
  return layer;
}

/* 添加指示图标 */
export function addSignIcon(point) {
  let pointFeature = new Feature({
    geometry: new Point(transform([point.longitude, point.latitude], "EPSG:4326", "EPSG:3857")),
  });
  if (getLayerByName('dynamicLayer')) {
    getLayerByName('dynamicLayer').getSource().clear();
    getLayerByName('dynamicLayer').getSource().addFeature(pointFeature);
    return;
  };
  let dynamicPointLayer = new VectorLayer({
    source: new VectorSource({
      features: [pointFeature],
    }),
    name: 'dynamicLayer',
    zIndex: 2,
  });
  signLayerArr.push({
    guid: point.guid,
    layer: dynamicPointLayer
  })
  map.addLayer(dynamicPointLayer);
  let radius = 30; // radius一定要放在监听事件外面
  let opacity = 1;
  map.on('postcompose', (event) => {
    if (!getLayerByName('dynamicLayer')) return;
    let dynamicFeatures = getLayerByName('dynamicLayer').getSource().getFeatures();
    opacity = (60 - radius) * (1 / 20); // 不透明度 radius为0时，不透明；radius为25时，透明
    dynamicFeatures.forEach((item) => {
      item.setStyle(new Style({
        image: new Circle({
          radius: radius,
          stroke: new Stroke({
            color: 'rgba(255, 148, 8, ' + opacity + ')',
            // color: 'rgba(5, 221, 242, ' + opacity + ')',
            width: 3,
          }),
        })
      }));
    });
    radius = radius + 0.5;
    radius = radius >= 60 ? 10 : radius;
    map.render(); // 重要
  });

  // // 创建一个图标对象
  // const iconFeature = new Feature({
  //   geometry: new Point(transform([point.longitude, point.latitude], "EPSG:4326", "EPSG:3857")),
  // });
  // // 定义图标样式
  // const iconStyle = new Style({
  //   image: new Icon({
  //     anchor: [0.5, 80],
  //     anchorXUnits: 'fraction',
  //     anchorYUnits: 'pixels',
  //     src: view,
  //   }),
  // });
  // // 设置图标的样式
  // iconFeature.setStyle(iconStyle);
  // // 创建图标源
  // const vectorSource = new VectorSource({
  //   features: [iconFeature],
  // });
  // // 创建图层并将其添加到地图中
  // const vectorLayer = new VectorLayer({
  //   source: vectorSource,
  // });
  // signLayerArr.push({
  //   guid: point.guid,
  //   layer: vectorLayer
  // })
  // map.addLayer(vectorLayer);
}

export function deleteSignLayer(guid) {
  map.removeLayer(signLayerArr.find(layer => layer.guid == guid).layer);
  signLayerArr = signLayerArr.filter(item => item.guid !== guid);
}